home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
UTIL
/
MEMORY
/
VIRTUASRC
/
!Virtual
/
s
/
virtual
< prev
Wrap
Text File
|
1993-09-07
|
22KB
|
703 lines
; virtual.s
; Part of the !Virtual distribution
; (c) bdb/nas/fo, 1992-3
; Assemble with:
;aasm s.Virtual Virtual -M -Q
GBLL DEBUG
DEBUG SETL {FALSE}
GBLL SWIS
SWIS SETL {TRUE}
GBLL OLD_VERSION
OLD_VERSION SETL {FALSE}
R0 RN 0
R1 RN 1
R2 RN 2
R3 RN 3
R4 RN 4
R5 RN 5
R6 RN 6
R7 RN 7
R8 RN 8
R9 RN 9
SL RN 10
FP RN 11
IP RN 12
SP RN 13
LR RN 14
PC RN 15
a1 RN 0
a2 RN 1
a3 RN 2
a4 RN 3
v1 RN 4
v2 RN 5
v3 RN 6
v4 RN 7
v5 RN 8
v6 RN 9
fp RN 10
ip RN 11
sp RN 12
lr RN 14
pc RN 15
N_bit * 1 :SHL: 31
Z_bit * 1 :SHL: 30
C_bit * 1 :SHL: 29
V_bit * 1 :SHL: 28
I_bit * 1 :SHL: 27
F_bit * 1 :SHL: 26
USR_mode * 0
FIQ_mode * 1
IRQ_mode * 2
SVC_mode * 3
GET Hdr.Swis
GET Hdr.Module
SUBT S.Virtual - virtual memory thing.
swibase * &47900 ; Acorn-allocated :-)
MACRO
CLRV $cc
CMP$cc pc,#0
MEND
MACRO
NOP
ANDEQ R0,R0,R0
MEND
; per task workspace
^ 0,ip
regs # 64
stacktop # 4
AREA |!!!Module$$Header|,CODE,READONLY
base & start-base
& init-base
& finish-base
& service-base
& title-base
& help-base
& cmdtab-base
[ SWIS
& swibase
& swihandler-base
& switable-base
& 0
]
title = "Virtual",0
help = "Virtual Memory",9,"0.37 (07 Sep 1993) by BDB/NAS/FO",0
cmdtab = "Virtual",0
ALIGN
& Virtual-base
= 0,0,20,0
& Virtualsynx-base
& Virtualhelp-base
& 0
Virtualhelp = "The *Virtual command allows a task to be run with virtual memory.",13,10
Virtualsynx = "Syntax: *Virtual [<command>] [-wimpslot <n>K] [-discslot <n>M] [-name <taskname>] [-nice <n>] [-ctrl] [-display] [-quit]",13,10
= " <command> is the command to be executed",13,10
= " -wimpslot sets the physical memory to be allocated; the virtual memory is set by the -discslot parameter, default 24M",13,10
= " -nice sets the task priority: 9 low priority, 0 high priority, default 4",13,10
= " -name sets the task name",13,10
= " -ctrl allows control characters through",13,10
= " -display opens the task window immediately, rather than waiting for a character to be printed",13,10
= " -quit makes the task quit after the command even if the task window has been opened",13,10
= "Note that fields must be in "" "" if they comprise more than one word", 0
[ SWIS
ALIGN
switable = "Virtual",0
= "TaskInfo",0
= "Physical",0
= 0
]
;SL env WriteS
;FP instantiation number
;IP currently preferred instantiation
;SP SVC mode stack
;Preserve R7-FP,SP
IMPORT |__RelocCode|
IMPORT Cinit
init STMDB SP!,{SL,FP,LR}
BL |__RelocCode|
MOV a1,IP
MOV sp,SP
SUB SP,SP,#1024
MOV fp,#0
BL Cinit
CLRV
TEQ R0,#0
TEQNEP PC,#V_bit+SVC_mode
ADD SP,SP,#1024
LDMIA SP!,{SL,FP,PC}
;R1 service number, may zero
;IP currently preferred instantiation
;SP a stack, SVC or IRQ
;Preserve R0,R2-R8 unless returning values
;May corrupt IP
service TEQ R1,#&11 ;Service_Memory
MOVNE PC,LR
ADR IP,base
TEQ R2,IP
MOVEQ R1,#0 ;claim
MOV PC,LR
;R0 command tail
;R1 command count
;IP currently preferred instantiation
;SP SVC mode stack
;Preserve R7-FP
Virtual STMFD SP!,{LR}
LDR IP,[IP]
MOV R2,R0 ;parameters
MOV R0,#2 ;Enter
ADR R1,title
SWI XOS_Module
LDMFD SP!,{PC}
;SL fatal flag
;FP instantiation number
;IP currently preferred instantiation
;SP SVC mode stack
;Preserve R7-FP,SP
IMPORT Cfinish
finish STMDB SP!,{SL,FP,LR}
MOV a1,IP
MOV sp,SP
SUB SP,SP,#1024
MOV fp,#0
BL Cfinish
CLRV
TEQ R0,#0
TEQNEP PC,#V_bit+SVC_mode
ADD SP,SP,#1024
LDMIA SP!,{SL,FP,PC}
[ SWIS
;(R9 SWI chunk *4)
;(SL routine addr)
;FP SWI number mod 64
;IP private word
;SP super stack (R9 LR swi-no SL FP IP)
;LR flags of caller with VC
;(R9,)SL-IP may be corrupted, return with MOVS
;R0-R8 as caller
;IRQs (NOT) disabled on entry, may enable them
swihandler LDR IP,[IP]
STMFD SP!,{R0-R3,LR}
CMP FP,#(endjumptable-jumptable)/4
ADDCC PC,PC,FP,LSL#2
B unknownswierror
jumptable B TaskInfo
B DoPhysical
endjumptable
unknownswierror LDMFD SP!,{R0-R3,LR}
ADR R0,unknownswimsg
ORRS PC,LR,#V_bit
unknownswimsg & &1E6
= "Unknown Virtual SWI",0
ALIGN
; R0 task id
; R1 Virtual address
; R2 buffer
; R3 len
; CDoPhysical passed private workspace as 5th arg
IMPORT CDoPhysical
DoPhysical
SUB SP,SP,#1024
STR IP,[SP,#1020] ;caution, IP=sp
ADD sp,SP,#1020
MOV fp,#0
BL CDoPhysical
ADD SP,SP,#1024
LDMFD SP!,{R0-R3,PC}^
]
; Virtual_TaskInfo
; Obtains information from the Virtual taskwindow module
; On entry
; R0 = 0 (actually we don't care)
; On exit
; R0 = 0 if not called from inside a virtual taskwindow, else non-zero
TaskInfo
MOV R0, #0 ; Always return not from here
LDMFD SP!,{R0-R3,PC}^
;R0 cmd string
;IP currently preferred instantiation
IMPORT |__main|
start
SWI OS_EnterOS
STR SP,svcstacktop ;record what a flat svcstack is
TEQ PC,#0
NOP
LDR ip,[IP]
MOV R6,R0
SWI OS_GetEnv
MOV sp,R1 ;stack at top of memory
MOV R0,#&8000
LDR R2,=&AAAAAAAA
[ OLD_VERSION
TEQ R0,sp
00 STRNE R2,[R0],#4
TEQ R0,sp
BNE %B00
|
MOV R3, R2
MOV R4, R2
MOV R5, R2
; TEQ R0,sp
00 STMIA R0!, {R2,R3,R4,R5}
CMP R0,sp
BLT %B00
MOV sp, #&10000 ; stack pointer at 32K to allow
; increasing wimpslot!
]
MOV a2,R6 ;command tail
MOV a1,ip ;worksp.
MOV fp,#0
BL |__main|
SWI OS_Exit
;**************** Start of Virtual mode interface routines *************
IMPORT CVSWIV
EXPORT VSWIV
VSWIV TST lr,#SVC_mode ;was it user mode?
LDRNE pc,workOldSWIV ;no, goto old routine
STR lr,templr
LDR lr,svcstacktop
TEQ lr,SP ;flat svcstack?
LDRNE lr,templr
LDRNE pc,workOldSWIV ;no, goto old routine
MOV lr,#1
STR lr,worksemaphore
TEQP pc,#SVC_mode ;Enable ints
NOP
LDR lr,workptr ;point at our workspace
STMIA lr,{R0-lr}^ ;Save all user regs
NOP
MOV ip,lr
LDR sp,stacktop
LDR lr,templr
STR lr,regs+15*4
MOV a1,ip
BIC a2,lr,#&FC000003
LDR a2,[a2,#-4]
MOV fp,#0
ADR lr,ToCode
ORR lr,lr,#SVC_mode
B CVSWIV ;must return w again
EXPORT VPrefetchAbort
VPrefetchAbort
STR lr,templr
MOV lr,#1
STR lr,worksemaphore
TEQP pc,#SVC_mode ;Enable ints
NOP
LDR lr,workptr ;point at our workspace
STMIA lr,{R0-lr}^ ;Save all user regs
NOP
MOV ip,lr
LDR sp,stacktop
LDR lr,templr
SUB lr,lr,#4 ;adjust
BIC R3,lr,#&FC000003
MOV R4,#4
B VWantAddr
;This is some static workspace, for when we don't have wksp ptr around.
;Used with care, we are still "reentrant" for use by different Wimp tasks.
;Set up anew each time we go into virtual mode.
;Its placed in the middle of the code that wants to use it to stay in
;addressing range.
EXPORT workptr
EXPORT workOldSWIV
EXPORT worksemaphore
EXPORT svcstacktop
workptr & 0 ;Pointer to workspace
workOldSWIV & 0 ;Place to forward SVC mode swi calls
worksemaphore & 0
templr & 0
svcstacktop & 0
EXPORT VDataAbort
VDataAbort
STR lr,templr
MOV lr,#1
STR lr,worksemaphore
TEQP pc,#SVC_mode ;Enable ints
NOP
LDR lr,workptr ;point at our workspace
STMIA lr,{R0-lr}^ ;Save all user regs
NOP
MOV ip,lr
LDR sp,stacktop
LDR lr,templr
BIC R0,lr,#&FC000003
STR R0,regs+15*4 ;For use of pc-relative
SUB lr,lr,#8 ;adjust
BIC R0,lr,#&FC000003
LDR R1,[R0] ;instruction
AND R2,R1,#&f0000 ;base register
LDR R3,[ip,R2,LSR #16-2] ;get its contents
TST R1,#(1:SHL:26)
BNE isSTRLDR
TST R1,#(1:SHL:23) ;direction
MOVEQ R6,#-4
MOVNE R6,#4
MOV R4,#0
MOV R5,R1,LSL#16
02 MOVS R5,R5,LSL#1
ADDCS R4,R4,R6
BNE %BT02
TST R1,#(1:SHL:21) ;writeback ?
SUBNE R3,R3,R4
STRNE R3,[ip,R2,LSR #16-2]
B VWantAddr
isSTRLDR TST R1,#(1:SHL:24)
BEQ %FT01 ;post index
MOV R4,R1,LSL#32-12 ;12 bits of offset
MOV R4,R4,LSR#32-12
TST R1,#(1:SHL:25)
BEQ %FT02 ;immed offset
AND R5,R4,#2_1111 ;reg Rm
LDR R5,[ip,R5,LSL#2]
AND R6,R4,#2_1100000 ; ALU instruction types, no register specific shift amounts
; So we have to divide by 2 here to get the 4 instruction
; offsets 0x00, 0x10, 0x20, 0x30
ADD pc,pc,R6, ASR#1
& 0
MOV R6,R4,LSR#7 ;immed shift LSL 0x00
MOV R4,R5,LSL R6
B %FT02
& 0
MOVS R6,R4,LSR#7 ;immed shift LSR 0x10
ORREQ R6,R6,#32
MOV R4,R5,LSR R6
B %FT02
MOVS R6,R4,LSR#7 ;immed shift ASR 0x20
ORREQ R6,R6,#32
MOV R4,R5,ASR R6
B %FT02
MOVS R6,R4,LSR#7 ;immed shift ROR 0x30
BEQ itsRRX
MOV R4,R5,ROR R6
B %FT02
itsRRX TEQ pc,lr,LSL#3 ;get aborted C flag
MOV R4,R5,RRX
02 TST R1,#(1:SHL:23)
SUBEQ R3,R3,R4 ;down
ADDNE R3,R3,R4 ;up
01 MOV R4,#4
; R3+R4 = access range, ip = worksp.
; resume to R0-R15 on stack
IMPORT CVWantAddr
VWantAddr
STR lr,regs+15*4 ;now save proper pc
[ DEBUG
MOV R0,R3
ADR R1,addr
MOV R2,#8
SWI XOS_ConvertHex8
LDR R0,[ip,#15*4]
ADR R1,addr2
MOV R2,#8
SWI XOS_ConvertHex8
ADR R0,mesg
SWI XOS_Write0
]
MOV a1,ip
MOV a2,R3
MOV a3,R4
MOV fp,#0
ADR lr,ToCode+SVC_mode
B CVWantAddr ;must return a1 again.
[ DEBUG
mesg = "Abort for addr &"
addr = "00000000 at "
addr2 = "00000000",13,10,0
ALIGN
]
;Return to user code, with callback semaphore zeroed.
;a1 points to workspace
ToCode
MOV lr,pc
TST lr,#3
ADREQ R0,ToCodeErr
SWIEQ OS_GenerateError
TEQP pc,#SVC_mode+I_bit ;disable ints
NOP
LDR lr,worksemaphore
SUBS lr,lr,#1
BNE VCallBack1
STR lr,worksemaphore
MOV lr,a1 ;reg block to a SVC reg
LDMIA lr,{R0-lr}^ ;load user regs
NOP
LDR lr,[lr,#15*4] ;user pc
MOVS pc,lr ;into user mode and go!
ToCodeErr & 0
= "Life is bad in ToCode",0
ALIGN
IMPORT CVCallBack
EXPORT VCallBack
VCallBack
MOV a1,IP
MOV ip,a1
LDR sp,stacktop
MOV lr,#1
VCallBack1
STR lr,worksemaphore
TEQP pc,#SVC_mode ;enable ints
NOP
MOV fp,#0
ADR lr,ToCode+SVC_mode
B CVCallBack ;must return a1 again.
;Regular Ticker CallEvery Centi-second
EXPORT OurCallEvery
OurCallEvery LDR IP,worksemaphore
TEQ IP,#0
ADDNE IP,IP,#1
STRNE IP,worksemaphore
MOVNES pc,lr
STMFD SP!,{lr}
MOV IP,pc
TEQP pc,#I_bit+SVC_mode
NOP
STMFD SP!,{lr}
SWI XOS_SetCallBack
LDMFD SP!,{lr}
TEQP IP,#0
NOP
LDMFD SP!,{pc}^
; Convert various sorts of events to C
IMPORT CVUpCall
EXPORT VUpCall
VUpCall STMFD SP!,{R1-IP,LR}
MOV a4,IP
MOV sp,SP
SUB SP,SP,#1024
MOV fp,#0
BL CVUpCall
ADD SP,SP,#1024
LDMFD SP!,{R1-IP,PC}^
EXPORT VError
VError SWI OS_GenerateError
EXPORT VExit
VExit SWI OS_Exit ;call in user mode to caught by VSWIV
; Convert various sorts of events to C
IMPORT CExtUpCall
EXPORT ExtUpCall
ExtUpCall STMFD SP!,{R1-IP,LR}
MOV a4,IP
MOV sp,SP
SUB SP,SP,#1024
MOV fp,#0
BL CExtUpCall
ADD SP,SP,#1024
LDMFD SP!,{R1-IP,PC}^
IMPORT CExtError
EXPORT ExtError
ExtError MOV ip,R0
LDR sp,stacktop
MOV fp,#0
BL CExtError
SWI OS_GenerateError
IMPORT CExtExit
EXPORT ExtExit
ExtExit
MOV a1,IP
MOV ip,a1
LDR sp,stacktop
MOV fp,#0
BL CExtExit
SWI OS_Exit
IMPORT CExtWriteC
K * &80000001
;return K to pass vector on with input flag values
;return K-1 for VC CC
;return K+1 for VC CS
;return K-2 for VS CC
EXPORT ExtWriteC
ExtWriteC
STMFD SP!,{R0-IP,LR}
SUB SP,SP,#8
STMIA SP,{SP,LR}^
NOP
MOV a2,IP
MOV sp,SP
SUB SP,SP,#1024
MOV fp,#0
BL CExtWriteC
ADD SP,SP,#1024
LDMIA SP,{SP,LR}^
NOP
ADD SP,SP,#8
CMP R0,#K
LDMEQFD SP!,{R0-IP,PC}^
LDMFD SP!,{R0-IP,LR,PC}
; Convert various sorts of events to C
IMPORT CNormWriteC
;return K to pass vector on with input flag values
;return K-1 for VC CC
;return K+1 for VC CS
;return K-2 for VS CC
EXPORT NormWriteC
NormWriteC
STMFD SP!,{R0-IP,LR}
SUB SP,SP,#8
STMIA SP,{SP,LR}^
NOP
MOV a2,IP
MOV sp,SP
SUB SP,SP,#1024
MOV fp,#0
BL CNormWriteC
ADD SP,SP,#1024
LDMIA SP,{SP,LR}^
NOP
ADD SP,SP,#8
CMP R0,#K
LDMEQFD SP!,{R0-IP,PC}^
LDMFD SP!,{R0-IP,LR,PC}
IMPORT CNormUpCall
EXPORT NormUpCall
NormUpCall STMFD SP!,{R1-IP,LR}
MOV a4,IP
MOV sp,SP
SUB SP,SP,#1024
MOV fp,#0
BL CNormUpCall
ADD SP,SP,#1024
LDMFD SP!,{R1-IP,PC}^
IMPORT CNormError
EXPORT NormError
NormError MOV ip,R0
LDR sp,stacktop
MOV fp,#0
BL CNormError
SWI OS_GenerateError
IMPORT CNormExit
EXPORT NormExit
NormExit
MOV a1,IP
MOV ip,a1
LDR sp,stacktop
MOV fp,#0
BL CNormExit
SWI OS_Exit
; Mode changing
; Now we use R12 as stack, less messy, and idempotent
EXPORT usermode
usermode MOV a2,lr
TEQP pc,#USR_mode
NOP
MOV pc,a2
EXPORT svcmode
svcmode MOV a2,lr
SWI XOS_EnterOS
MOV pc,a2
EXPORT CallEscapeHandler
CallEscapeHandler
MOV ip, sp
STMFD sp!, {v1, v2, fp, ip, lr, pc}
SUB fp, ip, #4
MOV v1, fp ; save fp and SP
MOV v2, SP
MOV SP, sp ; pass our stack on
MOV ip, a3 ; R11 escape condition
MOV sp, a2 ; R12
MOV lr, pc
MOV pc, a1 ; call user escape handler
MOV a1, sp ; R12 is return call back flag
MOV SP, v2 ; restore fp and SP
MOV fp, v1
LDMEA fp, {v1, v2, fp, sp, pc}^
END